#!/bin/sh
# Copyright (c) 2011, bkil.hu
# This program is free software and can be distributed under the terms of
# the GNU General Public License v2,
# see COPYING for detailed licensing terms.

# created on 2010-12-31 16:56

main(){
 MENCOPTS="-idx -ovc copy -oac copy"
 MPLOPTS="-osdlevel 3 -fs -vf pp=ac"
 #TODO: maybe run -forceidx on the source files
 local D=cut

 RECKILL=`dirname $0`/reckill.sh
 TRAPS="EXIT INT TERM"
 TMDIR=`mktemp -d`
 PARENT=$$
 IN=$TMDIR/stdin.fifo
 mkfifo $IN ||exit 1

 child "$D" &CHILD=$!
 local DELTEMP="
        rm -f -- $IN 2>/dev/null;
        rmdir -- $TMDIR 2>/dev/null"
 for a in $TRAPS; do
  [ $a = EXIT ] ||
   trap "$DELTEMP ;
         trap - $TRAPS ;
         $RECKILL -$a $CHILD \$$" $a
 done
 #TODO: why doesn't this propagate?
 trap "$DELTEMP ;
       $RECKILL $CHILD" EXIT

 dd of=$IN bs=1 #never exits
 $RECKILL $CHILD
}

child(){
 main2 "$@"
 printf "child process exit: " >&2
 $RECKILL $PARENT
}

main2(){
 local D="$1"
 local I="1"
 local DEL="$I/deleted"
 mkdir -p "$DEL" ||exit 1
 mkdir -p "$D" ||exit 1

 find "$I" -type f -iname '*.avi' |
 sort |
 while read F; do
  procfile "$F" ||exit 1
 done |
 { docuts "$D" ||exit 1 ;} |
 xargs mv -vt "$DEL"
 #TODO: maybe the renames could also be ran
 #      in parallel, but then either
 #      the conversion should be made less verbose
 #      or a new output window needs to be opened
 renames "$D" ||exit 1
}

renames(){
 local D="$1"
 find "$D" -type f |
 while read F;do
  local RETRY=1
  while [ -n "$RETRY" ]; do
   mplayer $MPLOPTS -really-quiet "$F" 2>/dev/null <$IN &MPL=$!
# TODO: trap?
   echo "$F" >&2
   printf 'enter new name (.=replay, blank=leave): ' >&2
   read NEW <$IN
   kill $MPL
   wait $MPL
   case "$NEW" in
    .)  echo retry >&2;;
    "") echo keep >&2
        RETRY="";;
    *)  mv -i "$F" `dirname $F`/`basename "$NEW" .avi`.avi <$IN
        RETRY=""
        echo >&2
   esac
  done
 done
 true
}

docuts(){
 local D="$1"
 while read F;do
  read S L &&
   cutf "$D" "$F" $S $L ||exit 1
  echo "$F"
 done |
 uniq
}

procfile(){
 local F="$1"
 { mplayer $MPLOPTS "$F" <$IN 2>/dev/null ||exit 1 ;}|
 mplayertosplits |
 splitstowindows |
 ziprepeat "$F"
}

ziprepeat(){
 local X="$1"
 while read Y; do
  echo "$X"
  echo "$Y"
 done
 true
}

splitstowindows(){
 awk '
  BEGIN{
   s=0
   before=4.0
   after=2.0
  }
  {
   u = (s-before>0 ? s-before : 0)
   print u " " ($1-u+after)
   s=$1
  }
  END{
   print s
  }
 '
}

cutf(){
 local D="$1"
 local F="$2"
 local S=$3
 local L=$4
 [ -n "$L" ] && local LL="-endpos $L"
 nice mencoder $MENCOPTS -o "$D/$S-`basename ${F}`" "$F" -ss $S $LL >&2 ||exit 1
}

mplayertosplits(){
 splitlines |
 onlypospause |
 onlybeforepause |
 bytimeandorder |
 onlynewestifnear
}

splitlines(){
 sed -r 's/ *A: *[0-9]+\.[0-9]+ V: *[0-9]+\.[0-9]+ +A-V:/\n&/g'
}

onlypospause(){
 grep -E '^ *A: *[0-9]+\.[0-9]+ V: *[0-9]+\.[0-9]+ +A-V:| *=+ +PAUSE +=+' |
 sed -r 's/ *=+ +PAUSE +=+/X/ ; s/^ *A: *[0-9]+\.[0-9]+ V: *([0-9]+\.[0-9]+) +.*$/\1/'
}

onlybeforepause(){
 grep -B 1 'X' |
 grep -E '^[0-9]+\.[0-9]+$'
 true
}

bytimeandorder(){
 nl -w1 -s ' ' |
 sed -r 's/^ *([0-9]+) +([^ ]*)$/\2 \1/' |
 LC_ALL=c sort -n
}

onlynewestifnear(){
 awk '
  BEGIN{
   u=-1
   v=0
  }
  function abs(x){
   return x>=0?x:-x
  }
  {
   if (u==-1){
    u=$1
    v=$2
   }
   else if (abs(u-$1) < 5.0){
    if ($2>v) {
     u=$1
     v=$2
    }
   } else {
    print u
    u=$1
    v=$2
   }
  }
  END{
   if (u!=-1)
    print u
  }'
}

main "$@"
